import 'dart:async';
import 'dart:io';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:karyo/karyo.dart';
import 'package:karyo/src/apis/api_client.dart';
import 'package:karyo/src/models/user.dart';
import 'package:karyo/src/models/user_mana.dart';
import 'package:rxdart/rxdart.dart';

class LoginBloc implements BlocBase {
  StreamController<User> _userController = StreamController<User>.broadcast();
  Stream<User> get user => _userController.stream;

  StreamController<bool> _syncDoneController =
      StreamController<bool>.broadcast();
  Stream<bool> get syncDone => _syncDoneController.stream;

  StreamController<File> _pickedImgFile = StreamController<File>.broadcast();
  Stream<File> get pickedImgFile => _pickedImgFile.stream;

  StreamController<bool> _forceSyncDoneController =
      StreamController<bool>.broadcast();
  Stream<bool> get forceSyncDone => _forceSyncDoneController.stream;

  StreamController<ManaUser> _manaUserController =
      StreamController<ManaUser>.broadcast();
  Stream<ManaUser> get manaUser => _manaUserController.stream;

  bool isLogin = false;
  CommonAPIClient client = new CommonAPIClient();
  String _token;

  File selectedAvatarFile;

  LoginBloc() {
    hello();
  }

  void setSelectedAvatarFile(File f) {
    _pickedImgFile.add(f);
    selectedAvatarFile = f;
  }

  Future<bool> syncAll() async {}

  void hello() async {
    // read token from local
    // and say hello to server to get latest user information
    var token = await SharedPreferenceUtil.get(SharedPreferenceUtil.KEY_TOKEN);
    if (token != null || token != '') {
      _token = token;
      GlobalSettings.setToken(token);
      GlobalSettings.setUranusToken(token);
      // request for user using token
      var user = await client.getUser(token);
      if (user != null) {
        _userController.sink.add(user);
      }
    }

    var _t =
        await SharedPreferenceUtil.get(SharedPreferenceUtil.KEY_TOKEN_MANA);
    // get MANA user
    var _manaUser = await client.getMANAUser(_token);
    if (_manaUser != null) {
      _manaUserController.add(_manaUser);
    }
  }

  void helloGetUser() async {
    var token = await SharedPreferenceUtil.get(SharedPreferenceUtil.KEY_TOKEN);
    _token = token;
    // request for user using token
    var user = await client.getUser(token);
    if (user != null) {
      _userController.sink.add(user);
    }
  }

  void forceSync() async {}

  // login logic, and the request login status
  // when APP starts
  Future<bool> login(name, password, context) async {
    if (name != '' && password != '') {
      var res = await client.login(name, password, context);
      if (res != null) {
        // 登录成功
        print('登录成功');
        isLogin = true;
        GlobalSettings.setUserAddr(res.userAddr);
        _userController.sink.add(res);
        hello();
        Navigator.of(context).pop();
        return true;
      } else {
        print('登录失败');
        return false;
      }
    } else {
      showToast(context, '用户名或者密码不能为空', COLOR_PRIMARY);
    }
  }

  Future<bool> register(name, password, context) async {
    if (name != '' && password != '') {
      var res = await client.register(name, password, context);
      if (res != null) {
        // 登录成功
        print('登录成功');
        isLogin = true;
        _userController.sink.add(res);
        return true;
      } else {
        print('登录失败');
        return false;
      }
    } else {
      showToast(context, '用户名或者密码不能为空', COLOR_PRIMARY);
      return false;
    }
  }

  Future<bool> registerWithInviteCode(
      name, password, inviteCode, context) async {
    if (name != '' && password != '' && inviteCode != "") {
      var res = await client.registerWithInviteCode(
          name, password, inviteCode, context);
      if (res != null) {
        // 登录成功
        print('登录成功');
        isLogin = true;
        _userController.sink.add(res);
        return true;
      } else {
        print('登录失败');
        return false;
      }
    } else {
      showToast(context, '用户名或密码或邀请码均不能为空', COLOR_PRIMARY);
      return false;
    }
  }

  Future<bool> updateUser(User newUser, BuildContext context) async {
    // update user info
    var _u = await client.updateUserInfo(newUser, _token, context);
    if (_u != null) {
      _userController.sink.add(_u);
      // showToast(context, "更新个人信息成功");
      return true;
    }
    // showToast(context, "更新个人信息失败");
    return false;
  }

  @override
  void dispose() {
    _userController.close();
    _syncDoneController.close();
    _forceSyncDoneController.close();
    _manaUserController.close();
  }
}
